package org.wheel.plugins.toolkit.util.sql.expander;

import cn.hutool.core.util.ObjectUtil;
import lombok.Getter;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.ExpressionVisitor;
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 行值比较表达式节点 (a,b,c) op (x,y,z)
 */
@Getter
public class RowComparisonExpr extends ASTNodeAccessImpl implements Expression {

    private final List<Expression> leftColumns;
    private final String             operator;
    private final List<Expression> rightItems;

    public RowComparisonExpr(List<Expression> left, String op, List<Expression> right) {
        this.leftColumns = new ArrayList<>(left);
        this.operator    = op;
        this.rightItems  = new ArrayList<>(right);
    }

    /* ---------------- JSQLParser 接口 ---------------- */
    @Override
    public void accept(ExpressionVisitor visitor) {
        // 目前仅用于 toString 还原，不再继续向下遍历
        throw new UnsupportedOperationException(
                "RowComparisonExpr 仅用于还原行值比较，未实现 ExpressionVisitor 遍历");
    }
    /* ---------------- 新接口（带返回值 & 上下文） ---------------- */
    @Override
    public <T, S> T accept(ExpressionVisitor<T> expressionVisitor, S context) {
        // 目前仅用于 toString 还原，不再继续向下遍历
        throw new UnsupportedOperationException(
                "RowComparisonExpr 仅用于还原行值比较，未实现 ExpressionVisitor 遍历");
    }

    /* ---------------- toString / equals / hashCode / clone ---------------- */
    @Override
    public String toString() {
        return "(" +
                leftColumns.stream().map(Expression::toString).collect(Collectors.joining(",")) +
                ") " + operator + " (" +
                rightItems.stream().map(Expression::toString).collect(Collectors.joining(",")) +
                ")";
    }

    /* ---------------- 必须覆写的 Object 方法 ---------------- */
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof RowComparisonExpr)) return false;
        RowComparisonExpr that = (RowComparisonExpr) o;
        return operator.equals(that.operator) &&
                leftColumns.equals(that.leftColumns) &&
                rightItems.equals(that.rightItems);
    }

    @Override
    public int hashCode() {
        return Objects.hash(leftColumns, operator, rightItems);
    }

    @Override
    public Expression clone() {
        // 深拷贝一份
        List<Expression> newLeft = new ArrayList<>();
        List<Expression> newRight = new ArrayList<>();

        leftColumns.forEach(e -> newLeft.add(ObjectUtil.clone(e)));
        rightItems.forEach(e -> newRight.add(ObjectUtil.clone(e)));
        return new RowComparisonExpr(newLeft, operator, newRight);
    }

}
